#include <monitor.h>
#include <QProcess>
#include <QString>
#include <QMessageBox>
#include <iostream>
#include <QMenu>
#include <QApplication>
#include <QToolTip>
#include <QDebug>
#include <QFont>
#include <cpumonitor.h>
#include <kwindowsystem.h>
#include <QWindow>
#include <unistd.h>
#include <memmonitor.h>




Monitor::Monitor(QWidget *parent)
    : QWidget(parent,Qt::Widget | Qt::WindowStaysOnTopHint),
      gv(std::make_unique<GpuMonitorFactory::GPUVendor>()),
      settingsWindow(new MonitorSettings(this))
{

    //    connect(kdk::WindowManager::self(),&kdk::WindowManager::skipSwitcherChanged,this,[=](const kdk::WindowId& windowId){
    //        if(m_lastestWindowId == windowId)
    //        {
    //            qDebug() << "skipSwitcherChanged";
    //        }
    //    });
    //    connect(kdk::WindowManager::self(),&kdk::WindowManager::skipTaskbarChanged,this,[=](const kdk::WindowId& windowId){
    //        if(m_lastestWindowId == windowId)
    //            qDebug() << "skipTaskbarChanged";
    //    });

    setAttribute(Qt::WA_TranslucentBackground);

    // 隐藏边框并置顶
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    setStyleSheet("background-color: rgba(0, 0, 0, 100); color: white;");

    // 设置窗口置顶（Wayland）
    connect(kdk::WindowManager::self(),&kdk::WindowManager::windowAdded,this,[=](const kdk::WindowId& windowId){

        if((quint32)getpid() == kdk::WindowManager::getPid(windowId))
        {
            currentWindowId = windowId;
            kdk::WindowManager::keepWindowAbove(currentWindowId);
        }
    });


    pluginManager = std::make_unique<PluginManager>();
    pluginManager->loadPluginsFromFolder("/home/DSOE1024/Code/QTProject/ukui-monitor-overlay/test-plugin/build-ukui-monitor-testplugin-unknown-Debug");



    layout = new QVBoxLayout(this);
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(layout);

    cpuUsageLabel = new QLabel("CPU占用率: --%", this);
    cpuUsageLabel->setToolTip("CPU占用率");
    layout->addWidget(cpuUsageLabel);

    cpuFreqLayout = new QVBoxLayout();

    //cpuFrequency = new QLabel("CPU频率: --%", this);
    //layout->addWidget(cpuFrequency);

    for (int i = 0; i <= CpuMonitor::getCpuCount(); ++i)
    {
        QLabel *cpuFreqLabel = new QLabel();
        cpuFrequencyLabels.emplace_back(cpuFreqLabel);
        cpuFreqLabel->setText(QString("CPU %1 频率: %2 Ghz").arg(i, 2).arg(CpuMonitor::getCurCpuFreq(0, CpuMonitor::FreqUnit::GHZ), 0, 'f', 1));
        cpuFreqLayout->addWidget(cpuFreqLabel);
    }

    layout->addLayout(cpuFreqLayout);

    cpuAvgFreqLabel = new QLabel("CPU平均频率：--%", this);
    layout->addWidget(cpuAvgFreqLabel);


    memUsageLabel = new QLabel("内存占用率: --%", this);
    memUsageLabel->setToolTip("内存使用率（不计交换空间）");
    layout->addWidget(memUsageLabel);

    gpuCoreUsageLabel = new QLabel("GPU核心占用率: --%", this);
    gpuCoreUsageLabel->setToolTip("GPU核心占用率");
    layout->addWidget(gpuCoreUsageLabel);

    gpuMemUsageLabel = new QLabel("GPU显存占用率: --%", this);
    gpuMemUsageLabel->setToolTip("GPU显存使用率");
    layout->addWidget(gpuMemUsageLabel);



    //GpuMonitorFactory::GPUVendor* gv = new GpuMonitorFactory::GPUVendor;
    // TODO：加上显卡型号判断逻辑

    char* vendor = kdk_display_get_vendor();
    std::cout << "GPU" << std::endl;
    std::cout << vendor << std::endl;

    if (vendor != nullptr) {
        std::string vendorStr(vendor);
        free(vendor); // 释放内存
        std::transform(vendorStr.begin(), vendorStr.end(), vendorStr.begin(), ::tolower);

        if (vendorStr.find("nvidia") != std::string::npos) {
            *gv = GpuMonitorFactory::GPUVendor::NV;
        } else if (vendorStr.find("amd") != std::string::npos) {
            *gv = GpuMonitorFactory::GPUVendor::AMD;
        } else if (vendorStr.find("intel") != std::string::npos) {
            *gv = GpuMonitorFactory::GPUVendor::Intel;
        } else {
            *gv = GpuMonitorFactory::GPUVendor::Unknown;
            qWarning() << "Unknown GPU vendor:" << vendorStr.c_str();
        }
    } else {
        *gv = GpuMonitorFactory::GPUVendor::Unknown;
        qWarning() << "Failed to get GPU vendor";
    }


    gpuMonitor = GpuMonitorFactory::createGpuMonitor(*gv);
    if (gpuMonitor == nullptr)
    {
        QMessageBox::warning(this, QString("警告"), QString("无法初始化显卡性能监视器，请提交issue并附上显卡型号信息"));
    }


    // 设置窗口高度为屏幕的20%并调整初始位置
    QTimer::singleShot(0, this, [this]() {
        adjustPosition();
    });

    // 刷新时间
    // TODO：未来改成可调整
    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &Monitor::updateStatus);
    timer->start(1000);

    // 绑定可见性改变信号
    connect(settingsWindow, &MonitorSettings::visibilityChanged, this, [this]() {
        updateLabelVisibility();
        this->adjustSize();
    });

    // 绑定字体大小改变信号
    connect(settingsWindow, &MonitorSettings::fontSizeChanged, this, [this]() {
        applyFontStylesToLabels();
        this->adjustSize();
    });

    // 绑定字体颜色改变信号
    connect(settingsWindow, &MonitorSettings::fontColorChanged, this, [this]() {
        applyFontStylesToLabels();
    });

    // 绑定CPU频率单位改变信号
    connect(settingsWindow, &MonitorSettings::cpuFreqUnitChanged, this, [this](){
        updateStatus();
    });

    // 启动后立即获取
    updateLabelVisibility();
    applyFontStylesToLabels();


    // 添加右键菜单
    setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, &QWidget::customContextMenuRequested, this, &Monitor::showContextMenu);
}

Monitor::~Monitor() {

}

void Monitor::restart()
{
    qApp->quit();
    QProcess::startDetached(qApp->applicationFilePath(), QStringList());
}

void Monitor::showContextMenu(const QPoint &pos)
{
    QMenu menu;
    menu.addAction("设置", [this]() {
        // 根据鼠标指针确定屏幕（适配多屏幕）
        //        QPoint globalMousePos = QCursor::pos();
        //        QScreen *targetScreen = QGuiApplication::screenAt(globalMousePos);
        //        if (!targetScreen)
        //        {
        //            targetScreen = QGuiApplication::primaryScreen();
        //        }
        //        QRect screenRect = targetScreen->availableGeometry();
        //        int windowHPos = (screenRect.width() - this->width()) / 2;
        //        int windowVPos = (screenRect.height() - this->height()) / 2;
        //settingsWindow->move(screenRect.left() + windowHPos, screenRect.top() + windowVPos);
        settingsWindow->show();
        settingsWindow->adjustSize();
    });
    menu.addAction("重启", this, &Monitor::restart);
    menu.addAction("退出", qApp, &QApplication::quit);
    menu.exec(mapToGlobal(pos));
}

void Monitor::updateLabelVisibility()
{
    cpuUsageLabel->setVisible(settingsWindow->isCpuUsageVisible());
    bool isCpuFreqVisible = settingsWindow->isCpuFreqVisible();

    // 0 是显示全部，1是平均
    int type = settingsWindow->getCpuFreqVisibleType();

    for (int i = 0; i < cpuFreqLayout->count(); ++i)
    {
        QWidget* widget = cpuFreqLayout->itemAt(i)->widget();
        if (widget)
        {
            widget->setVisible((type == 0) ? isCpuFreqVisible : false);
        }
    }
    cpuAvgFreqLabel->setVisible((type == 1) ? isCpuFreqVisible : false);


    memUsageLabel->setVisible(settingsWindow->isMemUsageVisible());
    gpuCoreUsageLabel->setVisible(settingsWindow->isGpuCoreUsageVisible());
    gpuMemUsageLabel->setVisible(settingsWindow->isGpuMemUsageVisible());

    this->adjustSize();
}

void Monitor::applyFontStylesToLabels()
{
    QFont font = this->font();
    font.setPixelSize(settingsWindow->getFontSize());

    QString colorStyle = QString("color: %1;").arg(settingsWindow->getFontColor().name());

    for (int i = 0; i < layout->count(); ++i)
    {
        QLayoutItem* item = layout->itemAt(i);
        QWidget* widget = item->widget();
        if (widget)
        {
            widget->setFont(font);
            widget->setStyleSheet(colorStyle + "margin: 0px; padding: 0px;");
        }

        // 未来写个递归匿名函数
        if (item->layout())
        {
            for (int j = 0; j < item->layout()->count(); ++j)
            {
                QLayoutItem* subitem = item->layout()->itemAt(j);
                if (subitem->widget())
                {
                    QWidget* subwidget = subitem->widget();
                    subwidget->setFont(font);
                    subwidget->setStyleSheet(colorStyle + "margin: 0px; padding: 0px;");

                }

            }

        }
    }
}


void Monitor::resizeEvent(QResizeEvent *event)
{
    //adjustPosition();
    // 避免点击空白区域错误缩放大小
    this->adjustSize();
    //QWidget::resizeEvent(event);
    event->accept();
}

void Monitor::adjustPosition()
{
    // 获取当前所在的屏幕
    QScreen *currentScreen = QGuiApplication::primaryScreen();

    QRect screenRect = currentScreen->availableGeometry();

    // 设置窗口高度为屏幕的20%
    //int windowHeight = screenRect.height() * 0.2;
    //this->setFixedHeight(windowHeight);

    // 调整窗口宽度以适应内容
    this->adjustSize();

    // 计算右上角位置
    int x = screenRect.right() - this->width();
    int y = screenRect.top();
    this->move(x, y);
}

void Monitor::getSysInfo()
{
    struct sysinfo info;
    if (sysinfo(&info) == 0) {

    }

}




void Monitor::updateStatus()
{
    cpuUsageLabel->setText(QString("CPU占用率: %1%").arg(CpuMonitor::getCpuUsage(), 0, 'f', 1));

    for (int i = 0; i < cpuFrequencyLabels.size(); ++i)
    {
        //QLabel *cpuFreqLabel = cpuFrequencyLabels[i];
        if (settingsWindow->getCpuFreqVisibleUnit() == CpuMonitor::FreqUnit::GHZ)
        {
            cpuFrequencyLabels[i]->setText(QString("CPU %1 频率: %2 Ghz").arg(i, 2).arg(CpuMonitor::getCurCpuFreq(0, CpuMonitor::FreqUnit::GHZ), 0, 'f', 1));
        }
        else if (settingsWindow->getCpuFreqVisibleUnit() == CpuMonitor::FreqUnit::MHZ)
        {
            cpuFrequencyLabels[i]->setText(QString("CPU %1 频率: %2 Mhz").arg(i, 2).arg(CpuMonitor::getCurCpuFreq(0, CpuMonitor::FreqUnit::MHZ), 0, 'f', 1));
        }
    }

    if (settingsWindow->getCpuFreqVisibleUnit() == CpuMonitor::FreqUnit::GHZ)
    {
        cpuAvgFreqLabel->setText(QString("CPU平均频率: %1 Ghz").arg(CpuMonitor::getAvgCpuFreq(settingsWindow->getCpuFreqVisibleUnit()), 0, 'f', 1));

    }
    else if (settingsWindow->getCpuFreqVisibleUnit() == CpuMonitor::FreqUnit::MHZ)
    {
        cpuAvgFreqLabel->setText(QString("CPU平均频率: %1 Mhz").arg(CpuMonitor::getAvgCpuFreq(settingsWindow->getCpuFreqVisibleUnit()), 0, 'f', 1));
    }
    memUsageLabel->setText(QString("内存占用率: %1%").arg(MemMonitor::getMemUsage(), 0, 'f', 1));
    if (gpuMonitor != nullptr)
    {
        float coreUsage = gpuMonitor->getGpuCoreUsage();
        float memUsage = gpuMonitor->getGpuMemUsage();
        
        gpuCoreUsageLabel->setText(QString("GPU核心占用率: %1").arg(
            coreUsage == 0 ? "none" : QString("%1%").arg(coreUsage, 0, 'f', 1)));
        
        gpuMemUsageLabel->setText(QString("GPU显存占用率: %1").arg(
            memUsage == 0 ? "none" : QString("%1%").arg(memUsage, 0, 'f', 1)));
    }
    else
    {
        gpuCoreUsageLabel = new QLabel("GPU核心占用率: --%", this);
        gpuMemUsageLabel = new QLabel("GPU显存占用率: --%", this);
    }

    try
    {
        // 更新插件数据
        for (auto *plugin : pluginManager->getPlugins())
        {
            if (!plugin) continue;
            QString name = plugin->displayName();
            QVariant value = plugin->getMonitoringValue();
            QLabel *label = findChild<QLabel *>(name);
            if (!label)
            {
                label = new QLabel(this);
                label->setObjectName(name);
                layout->addWidget(label);
            }
            label->setText(QString("%1: %2").arg(name).arg(value.toString()));
        }

    }
    catch (const std::exception &e)
    {
        qDebug() << "Exception in updateStatus:" << e.what();
    }

}

void Monitor::mousePressEvent(QMouseEvent *event)
{
    mMoveing = true;
    // 记录下鼠标相对于窗口的位置
    // event->globalPos()鼠标按下时，鼠标相对于整个屏幕位置
    // pos() this->pos()鼠标按下时，窗口相对于整个屏幕位置
    mMovePosition = event->globalPos() - pos();
    this->adjustSize();
    event->accept();
}

void Monitor::mouseMoveEvent(QMouseEvent *event)
{
    if (mMoveing && (event->buttons() == Qt::LeftButton)
            && (event->globalPos() - mMovePosition).manhattanLength() > QApplication::startDragDistance())
    {
        move(event->globalPos() - mMovePosition);
        mMovePosition = event->globalPos() - pos();
    }
    this->adjustSize();
    event->accept();
}

void Monitor::moveEvent(QMoveEvent* event)
{
    //adjustPosition();
    QWidget::moveEvent(event);
}

void Monitor::mouseReleaseEvent(QMouseEvent *event)
{
    mMoveing = false;
}
